#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QApplication>
#include <QDebug>
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QLineEdit>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QDir>
#include <QTimer>
#include <QSettings>
#include <QMessageBox>
#include <QThread>
#include <QStandardPaths>
#include <QDate>
#include <QStatusBar>
#include <QLabel>
#include <QApplication>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 设置窗口标题为 "loop测试"
    this->setWindowTitle("loop测试");
    process1 = new QProcess(this); // 创建第一个 QProcess 对象
    // 创建输出读取器
    reader1 = new OutputReader(process1);

    // 启动线程
    reader1->moveToThread(&thread1);

    connect(&thread1, &QThread::started, reader1, &OutputReader::readOutput);

    connect(reader1, &OutputReader::outputReceived, this, &MainWindow::handleOutput1);

    QSettings settings("config.ini", QSettings::IniFormat);
    // 从配置文件中读取上次保存的第一个路径
    QString mdir1 = settings.value("DO/Path", "").toString();
    ui->lineEdit_2->setText(mdir1);
    // 从配置文件中读取上次保存的第二个路径
    QString mdir2 = settings.value("DevDO/Path", "").toString();
    ui->lineEdit_3->setText(mdir2);
    // 从配置文件中读取上次保存的第二个路径
    QString mdir3 = settings.value("DevDI/Path", "").toString();
    ui->lineEdit_4->setText(mdir3);

    // 创建状态栏
    QStatusBar *statusBar = new QStatusBar(this);
    this->setStatusBar(statusBar);

    // 创建 QLabel 用于显示文本
    statusLabel = new QLabel(this);
    statusLabel->setStyleSheet("color: red;"); // 设置字体颜色为红色
    statusLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); // 设置文本对齐方式

    // 将 QLabel 添加到状态栏
    statusBar->addWidget(statusLabel);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_DO_Path_pushButton_clicked()
{
    // 使用原生对话框选择目录
    QString mdir =  ui->lineEdit_2->text();
    QString dir = QFileDialog::getOpenFileName(
           this,
           "选择目录",
             mdir, // 指定默认显示的文件夹路径
           "All Files (*);;Text Files (*.txt)" // 文件过滤器
       );

       if (!dir.isEmpty())  {
           ui->lineEdit_2->setText(QDir::toNativeSeparators(dir));
           // 声明 QSettings 对象
           QSettings settings("config.ini", QSettings::IniFormat);
           // 保存这次选择的路径到配置文件
           settings.setValue("DO/Path", dir);
           comDO = dir;
           qDebug() << "comDO:" << comDO;

       }

       QString com = ui->lineEdit_2->text();
       // 声明 QSettings 对象
       QSettings settings("config.ini", QSettings::IniFormat);
       // 保存这次选择的路径到配置文件
       settings.setValue("DO/Path", com);
       qDebug() << "comDO:" << com;


       QString path = com;

       // 使用 QFileInfo 解析路径
       QFileInfo fileInfo(path);

       // 获取文件名（最后一部分）
       comDO = fileInfo.fileName();

       // 获取路径部分（其他部分）
       pathDO = fileInfo.path();

       qDebug() << "文件名:" << comDO;  // 输出: acp3401_DO
       qDebug() << "文件路径:" << pathDO;  // 输出: /home/lll/..../Code

}




void MainWindow::on_dev_DI_pushButton_clicked()
{
    // 使用原生对话框选择目录
    QString mdir =  ui->lineEdit_4->text();
    QString dir = QFileDialog::getOpenFileName(
           this,
           "选择目录",
             mdir, // 指定默认显示的文件夹路径
            "All Files (*);;Text Files (*.txt)" // 文件过滤器
       );

       if (!dir.isEmpty())  {
           ui->lineEdit_4->setText(QDir::toNativeSeparators(dir));
           // 声明 QSettings 对象
           QSettings settings("config.ini", QSettings::IniFormat);
           // 保存这次选择的路径到配置文件
           settings.setValue("DevDI/Path", dir);
           devDI = dir;
           qDebug() << "devDI:" << devDI;
       }
       devDI = ui->lineEdit_4->text();
       // 声明 QSettings 对象
       QSettings settings("config.ini", QSettings::IniFormat);
       // 保存这次选择的路径到配置文件
       settings.setValue("DevDI/Path", devDI);
       qDebug() << "devDI:" << devDI;
}

void MainWindow::on_dev_DO_pushButton_clicked()
{
    // 使用原生对话框选择目录
    QString mdir =  ui->lineEdit_3->text();
    QString dir = QFileDialog::getOpenFileName(
           this,
           "选择目录",
             mdir, // 指定默认显示的文件夹路径
           "All Files (*);;Text Files (*.txt)" // 文件过滤器
       );

       if (!dir.isEmpty())  {
           ui->lineEdit_3->setText(QDir::toNativeSeparators(dir));
           // 声明 QSettings 对象
           QSettings settings("config.ini", QSettings::IniFormat);
           // 保存这次选择的路径到配置文件
           settings.setValue("DevDO/Path", dir);
           devDO = dir;
           qDebug() << "devDO:" << devDO;
       }

       // 声明 QSettings 对象
       QSettings settings("config.ini", QSettings::IniFormat);
       // 保存这次选择的路径到配置文件
       settings.setValue("DevDO/Path", devDO);

       qDebug() << "devDO:" << devDO;
}

void MainWindow::on_lineEdit_3_cursorPositionChanged(int arg1, int arg2)
{
    (void)arg1; // 忽略未使用的参数
    (void)arg2; // 忽略未使用的参数

    devDO = ui->lineEdit_3->text();

    // 声明 QSettings 对象
    QSettings settings("config.ini", QSettings::IniFormat);
    // 保存这次选择的路径到配置文件
    settings.setValue("DevDO/Path", devDO);

    qDebug() << "devDO:" << devDO;
}

void MainWindow::on_lineEdit_4_cursorPositionChanged(int arg1, int arg2)
{
    (void)arg1; // 忽略未使用的参数
    (void)arg2; // 忽略未使用的参数
    devDI = ui->lineEdit_4->text();
    // 声明 QSettings 对象
    QSettings settings("config.ini", QSettings::IniFormat);
    // 保存这次选择的路径到配置文件
    settings.setValue("DevDI/Path", devDI);
    qDebug() << "devDI:" << devDI;

}


void MainWindow::on_lineEdit_2_cursorPositionChanged(int arg1, int arg2)
{

    (void)arg1; // 忽略未使用的参数
    (void)arg2; // 忽略未使用的参数
    QString com = ui->lineEdit_2->text();
    // 声明 QSettings 对象
    QSettings settings("config.ini", QSettings::IniFormat);
    // 保存这次选择的路径到配置文件
    settings.setValue("DO/Path", com);
    qDebug() << "com:" << com;


    QString path = com;

    // 使用 QFileInfo 解析路径
    QFileInfo fileInfo(path);

    // 获取文件名（最后一部分）
    comDO = fileInfo.fileName();

    // 获取路径部分（其他部分）
    pathDO = fileInfo.path();

    qDebug() << "comDO:" << comDO;  // 输出: acp3401_DO
    qDebug() << "pathDO:" << pathDO;  // 输出: /home/lll/..../Code

}


void MainWindow::on_lineEditDO_cursorPositionChanged(int arg1, int arg2)
{
    (void)arg1; // 忽略未使用的参数
    (void)arg2; // 忽略未使用的参数

    SerialNumber = ui->lineEditDO->text();
    // 声明 QSettings 对象
    QSettings settings("config.ini", QSettings::IniFormat);
    // 保存这次选择的路径到配置文件
    settings.setValue("SerialNumber", SerialNumber);
    qDebug() << "SerialNumber:" << SerialNumber;
}

void MainWindow::on_pushButton_3_clicked()
{
    TextLog.clear();
    stopProcess(process1, reader1, &thread1);
    statusLabel->setText(""); // 清空 QLabel 的文本
    //初始0
    // SetFramesColor(frames1, COLOR_RED);
    // SetFramesColor(frames2, COLOR_RED);
    TextLog.clear();
    //停止测试
    ui->pushButton->setText("开始测试");
    ui->pushButton->setEnabled(true);

    qDebug() << "复位";
}

void MainWindow::on_pushButtonDI_Set_clicked()
{
    // DI同步检测
    QString Channel = ui->comboBoxDI_Channel->currentText();
    qDebug() <<"DI 通道:" << Channel ;
    if( Channel == "全部通道")
    {
       startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "3" << "38");   //Channel set 1
    }
    else
    {
       startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "3" << Channel);   //Channel set 1
    }
}




void MainWindow::on_pushButtonDO_Set_clicked()
{
    QString Info;
    QString Channel = ui->comboBoxDO_Channel->currentText();
    QString Level = ui->comboBoxDO_Level->currentText();
    qDebug() <<"DO 通道:" << Channel << "设置为" << Level;
    if( Channel == "全部通道")
    {
        qDebug() << Channel;
        if(ui->comboBoxDO_Level->currentText() == "高电平")
        {
            startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "1" << "30");
        }else
        {
            startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "2" << "30");
        }
    }else if (Channel == "自动测试")
    {
        startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "0" << "0");
    }
    else
    {
        if(ui->comboBoxDO_Level->currentText() == "高电平")
        {
          startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "1" << Channel);   //Channel set 1
        }else
        {
          startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "2" << Channel);   //Channel set 0
        }
    }
}

//启动测试
void MainWindow::on_pushButton_clicked()
{
      qDebug() << "11111";
      startProcessWithDirectory(process1, reader1, &thread1, pathDO, comDO, QStringList() << devDO << devDI << "0" << "0");
}
//停止测试
void MainWindow::on_stopButton_clicked()
{
    qDebug() << "22222";
    TextLog.clear();
    stopProcess(process1, reader1, &thread1);
    statusLabel->setText(""); // 清空 QLabel 的文本
  //  ui->pushButton->setEnabled(true);  // 启用按钮
}
void MainWindow::startProcessWithDirectory(QProcess *process, OutputReader *reader, QThread *thread, const QString &workingDirectory, const QString &program, const QStringList &arguments)
{
    qDebug() << "工作目录:" <<  workingDirectory <<  "文件名" <<  program  <<  "参数"<< arguments ;
    process->setWorkingDirectory(workingDirectory);
    process->start(program, arguments);
    if (!process->waitForStarted())
    {
        QString aa = process->errorString();
        qDebug() << "无法启动程序:" << process->errorString();
        QMessageBox::critical(this, "程序启动失败", aa);
        // return ;
    }
    else
    {
        reader->startReading(); // 重置 running 标志
        thread->start();
        qDebug()<< "程序启动";
    }
    reader->startReading(); // 重置 running 标志
    thread->start();
}

void MainWindow::stopProcess(QProcess *process, OutputReader *reader, QThread *thread)
{
    process->terminate();
    if (!process->waitForFinished(3000)) // 等待 3 秒
    {
        process->kill(); // 如果没有停止，强制终止
    }
    process->close(); // 关闭 QProcess 对象
    reader->stopReading();
    thread->quit();
    thread->wait();
}
//输出捕获处理
void MainWindow::handleOutput1(const QByteArray &output)
{
    qDebug() << "Output from DO:" << output;
    processOutput(output);
}


void MainWindow::processOutput(const QByteArray &output)
{
    QString outputStr = output.trimmed();
//    qDebug() << "==================\n" << output<<"\n==================\n";
    TextLog.append(outputStr);
    TextLog.append("\n");
    appendText(outputStr);
    // ui->textEdit->setText(TextLog);
    // 更新状态栏文本
   //  if (statusLabel) {
   //      statusLabel->setText(outputStr);
   //  }
   // if(outputStr.contains("结束"))
   // {
   //   QMessageBox::information(this, "测试结束", "测试已成功完成！");
   //   statusLabel->setText(""); // 清空 QLabel 的文本
   // }
}

void MainWindow::on_pushButton_9_clicked()
{
    QString T = QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss");
    // 生成带时间戳的文件名建议（格式：校准数据_时分秒）
    QString defaultName = QString("%1_%2_%3.txt")
                            .arg("LOOP")
                            .arg(SerialNumber)
                            .arg(T);

    // 文件对话框配置
    QString fileName = QFileDialog::getSaveFileName(
        this,
        tr("导出校准数据"),
        defaultName,  // 初始路径
        tr("文本文件 (*.txt);;所有文件 (*)")
    );

    if (fileName.isEmpty())  return;

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly  | QIODevice::Truncate | QIODevice::Unbuffered)) {
        QMessageBox::warning(this, "错误", QString("文件创建失败：%1").arg(file.errorString()));
        return;
    }
//    TextLog.append("123\n");
//    TextLog.append("789");
    QTextStream stream(&file);
    stream << TextLog;

    // 修改文件权限，使其对所有用户可读写
    file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadGroup | QFile::WriteGroup | QFile::ReadOther | QFile::WriteOther);
    file.close();
}
void MainWindow:: appendText(const QString &text) {
    QTextCharFormat format;
    const bool hasError = text.contains("错误");
    // const bool hasCorrect = text.contains("正确");
     const bool hasEnd = text.contains("结束");

    ui->textEdit->append(text);
     // 手动滚动到底部
     QTextCursor cursor =ui-> textEdit->textCursor();
     cursor.movePosition(QTextCursor::End); // 将光标移动到文档末尾
     ui->textEdit->setTextCursor(cursor);      // 更新光标位置
    // 仅记录包含“错误”的条目
    if (hasError) {
        errorList.append(text);  // 将错误文本添加到错误列表
    }
    if(hasEnd)
    {
        finishAppending();
    }
}

void MainWindow::finishAppending() {
    if (!errorList.isEmpty()) {
        qDebug() << "=== 测试信息 ===";
        qDebug() << "共发现" << errorList.count() << "个错误：";
        QString errInfo = QString("共发现 %1 个错误：").arg(errorList.count());
        ui->textEdit->append("=== 测试信息 ===");
        ui->textEdit->append(errInfo);
        // 手动滚动到底部
        QTextCursor cursor =ui-> textEdit->textCursor();

        for (const QString &error : errorList) {
            // qDebug() << "▶" << error;  // 每条错误前加上“▶”符号
             ui->textEdit->append("▶" +error);
        }
         ui->textEdit->append("=============");
        cursor.movePosition(QTextCursor::End); // 将光标移动到文档末尾
        ui->textEdit->setTextCursor(cursor);      // 更新光标位置
    }else
    {
        ui->textEdit->append("全部正确");
        ui->textEdit->append("=============");
        QTextCursor cursor =ui-> textEdit->textCursor();
        cursor.movePosition(QTextCursor::End); // 将光标移动到文档末尾
        ui->textEdit->setTextCursor(cursor);      // 更新光标位置
    }
    errorList.clear();
}
